#include "Reloj.h"
#include "unistd.h"

using namespace TP::Juego::Motorizacion::Sincronizacion;

Reloj::Reloj(Ticks pUnidadTiempo) {
	this->_tiempoTranscurrido = 0;
	this->_unidadTiempo = pUnidadTiempo;
}

Reloj::~Reloj() {
	this->_temporizables.clear();
}

ITemporizable* Reloj::addTemporizable(ITemporizable* pTemporizable) {
	if (pTemporizable)
		this->_temporizables.push_back(pTemporizable);
}

ITemporizable* Reloj::removerTemporizable(ITemporizable* pTemporizable) {
	// Identifico la posicion del elemento temporizable.
	int cur = 0;
	while (cur < _temporizables.size() && pTemporizable != _temporizables[cur])
		cur++;

	// Remuevo el elemento temporizable en caso de existir en la coleccion.
	if (cur < this->_temporizables.size())
		this->_temporizables.erase(this->_temporizables.begin() + cur);

	return pTemporizable;
}

Ticks Reloj::getTiempo() {
	return this->_tiempoTranscurrido;
}

void Reloj::notificarAvanceTiempo() {
	for (vector<ITemporizable*>::iterator it = this->_temporizables.begin();
			it != this->_temporizables.end(); ++it)
		(*it)->notificacionAvanceTiempo(this->_unidadTiempo);
}

Ticks Reloj::correr() {
	this->_tiempoTranscurrido += this->_unidadTiempo;
	this->notificarAvanceTiempo();

	return this->_unidadTiempo;
}

void Reloj::Iniciar() throw (Excepcion&) {
	try {
		this->_corriendo = true;
		Thread::Iniciar();
	}
	catch (Excepcion& pEx) {
		throw pEx;
	}
}

void Reloj::Finalizar() throw (Excepcion&) {
	try {
		this->_corriendo = false;
		Thread::Finalizar();
	}
	catch (Excepcion& pEx) {
		throw pEx;
	}
}

void Reloj::tarea() {
	while (_corriendo) {
		this->notificarAvanceTiempo();
		usleep(1000000 / 12.5);
	}
}